package common.interfaces;

import java.sql.SQLException;
import java.util.Collection;

import msg.*;
import user.User;

import common.exceptions.InvalidUserException;

/**
 * A class whose role it is to manage the persistence of messages and events
 * 
 * @author Gal Lalouche
 */
public interface IMessagePersistencyManager extends IDAL<Message, Long>, IMessageVisitor<Message> {
	
	/**
	 * Persists the message
	 * 
	 * @param message The message to persist
	 * @throws InvalidUserException If the message's poster is not registered to they system
	 * @throws SQLException
	 */
	void store(Message message) throws SQLException, InvalidUserException;
	
	/**
	 * Removes all messages and events posted by the user
	 * 
	 * @param user The user
	 * @throws InvalidUserException If the user is not registered to they system
	 * @throws SQLException
	 */
	void removeAllUserMessagesAndEvents(User user) throws SQLException, InvalidUserException;
	
	/**
	 * @return The maximum id used by any persisted message
	 * @throws SQLException
	 */
	long getLastId() throws SQLException;
	
	/**
	 * Gets all messages and events posted by a the user
	 * 
	 * @param user The user
	 * @return All the messages posted by the user
	 * @throws InvalidUserException If the user is not registered to the system
	 * @throws SQLException
	 */
	Collection<Message> getAllUserPosts(User user) throws SQLException, InvalidUserException;
	
	/**
	 * Gets all events (not messages) posted by a user
	 * 
	 * @param user The user
	 * @param since Only show messages newer than this; use <code>null</code> for none
	 * @param includePastEvents If true, past events (that are already over) will be included
	 * @return All the events posted by the user
	 * @throws InvalidUserException If the user is not registered to the system
	 * @throws SQLException
	 */
	Collection<EventMessage> getAllUserEvents(User user, Long since, boolean includePastEvents)
			throws InvalidUserException, SQLException;
	
	/**
	 * Gets all messages only (not events) posted by a user
	 * 
	 * @param user The user
	 * @param since Only show messages newer than this; use <code>null</code> for none
	 * @return All messages sans events posted by the user
	 * @throws InvalidUserException If the user is not registered to the system
	 * @throws SQLException
	 */
	Collection<Message> getAllUserMessagesOnly(User user, Long since) throws InvalidUserException, SQLException;
	
	/**
	 * Gets all the messages (not events) that are within a certain a radius from a certain coordinate
	 * 
	 * @param center The center the radius is searched against
	 * @param distance The maximum distance from the coordinate
	 * @param since Only show messages newer than this; use <code>null</code> for none
	 * @return A collection of all the messages in the radius
	 * @throws ArithmeticException If {@code distance < 0}
	 * @throws SQLException
	 */
	Collection<Message> getAllMessagesInRadius(Location center, double distance, Long since) throws SQLException;
	
	/**
	 * Gets all the events that are within a certain a radius from a certain coordinate
	 * 
	 * @param center The center the radius is searched against
	 * @param distance The maximum distance from the coordinate
	 * @param since Only show messages newer than this; use <code>null</code> for none
	 * @param includePastEvents If true, past events (that are already over) will be included
	 * @return A collection of all the events in the radius
	 * @throws ArithmeticException If {@code distance < 0}
	 * @throws SQLException
	 */
	Collection<EventMessage> getAllEventsInRadius(Location center, double distance, Long since,
			boolean includePastEvents) throws SQLException;
}
